from django.db import transaction
from rest_framework import serializers

from BYD_ERP.utils.get_inventory import get_inventory_by_goods
from goods_info.models import GoodsModel, GoodsInventoryModel, AttachmentModel
from goods_info.serializer.units_serializer import UnitsSerializer
from goods_info.serializer.goods_category_serializer import GoodsCategorySerializer
from goods_info.serializer.attachment_serializer import AttachmentSerializer


class GoodsInventorySerializer(serializers.ModelSerializer):
    """
        货品库存的序列化器，和反序列化
    """

    class Meta:
        model = GoodsInventoryModel
        fields = '__all__'


class GoodsBaseSerializer(serializers.ModelSerializer):
    """
        货品(存货档案)新增、修改的序列化器，和反序列化
    """
    # required=True必须存在，不可或缺
    # 同一种货品肯定对应多个仓库
    goods_inventory_list = GoodsInventorySerializer(many=True, required=True)

    class Meta:
        model = GoodsModel
        fields = '__all__'

    def create(self, validated_data):
        # 该新增商品的库存对象的列表
        item_list = validated_data.pop('goods_inventory_list')
        # 执行pop后，validated_data中就没了库存信息了
        # **validated_data带两个*，意思是将validated_data中的值展开，使用create创建到GoodsModel中，返回给goods。
        # 新增纯粹的商品信息，就是不包含库存信息。
        with transaction.atomic():
            goods = GoodsModel.objects.create(**validated_data)
            for item in item_list:
                # 拿到期初库存，赋给当前库存，如果拿不到，将0赋给当前库存
                item['cur_inventory'] = item.get('init_inventory', 0)
                # **item：将item中的值展开
                GoodsInventoryModel.objects.create(goods_id=goods, **item)
        return goods

    def update(self, instance, validated_data):
        # 该新增商品的库存对象的列表
        item_list = validated_data.pop('inventory_list')
        with transaction.atomic():
            for item in item_list:
                # 遍历每条库存信息，并修改最高安全库存和最低安全库存
                GoodsInventoryModel.objects.filter(goods_id=instance.id, warehouse__name=item['warehouse_name']).update(
                    lowest_inventory=item.get('lowest_inventory', 0),
                    highest_inventory=item.get('highest_inventory', 0)
                )
            goods = super(GoodsBaseSerializer, self).update(instance=instance, validated_data=validated_data)
        return goods


class GoodsGetSerializer(serializers.ModelSerializer):
    """
    商品查询的序列化器
    目标：
        1.把商品的单位--所有信息展示出来
        2.展示商品信息所属的商品类别--所有信息展示出来
        3.展示商品的所有附件图片--所有图片信息展示出来
        4.展示商品所有仓库的总库存信息
    """
    # 只展示基本单位名称
    # source：来源
    # units = serializers.CharField(source='basic_name')
    # 展示单位的所有信息
    units = UnitsSerializer(read_only=True)
    # 展示商品类别
    category = GoodsCategorySerializer(read_only=True)

    images_list = serializers.SerializerMethodField(read_only=True)

    # 商品的当前总库存数量
    cur_inventory = serializers.SerializerMethodField(read_only=True)

    # 同一种货品肯定对应多个仓库
    inventory_list = GoodsInventorySerializer(many=True, read_only=True)

    class Meta:
        model = GoodsModel
        fields = '__all__'

    # obj：当前商品的对象
    def get_images_list(self, obj):
        image_result = []
        print('----------1----------')
        print('images_list:', obj.images_list)
        if obj.images_list:
            # images_list属性是由多个附件的ID组成，中间使用逗号隔开
            # split(',')用逗号进行分割
            ids = obj.images_list.split(',')
            # 这里获得的ids是字符串格式
            print('----------2----------')
            print(obj.images_list)
            if ids:
                for i in ids:
                    # 这里获得的image是一个模型对象，需要将模型对象转换成字典
                    # image = AttachmentModel.objects.get(id=int(i))
                    image = AttachmentModel.objects.get(id=int(i))
                    # 使用data将会自动的把模型对象instance转换成字典
                    image_result.append(AttachmentSerializer(instance=image).data)
        return image_result

    def get_cur_inventory(self, obj):
        result = get_inventory_by_goods(obj.id)
        # 如果result有就返回result，如果result没有就返回0。
        return result if result else 0
